package entity

import (
	dom "a-common/domain"
	"sort"
)

// SysMenu 系统菜单表
type SysMenu struct {
	MenuId         int64  `xorm:"pk autoincr notnull"` // 菜单ID
	MenuName       string `xorm:"varchar(50) notnull"` // 菜单名称
	ParentId       int64  // 父菜单ID
	OrderNum       int    `xorm:"default(0)"`              // 显示顺序
	Path           string `xorm:"varchar(200)"`            // 路由地址
	Component      string `xorm:"varchar(255)"`            // 组件路径
	Query          string `xorm:"varchar(255)"`            // 路由参数
	IsFrame        string `xorm:"varchar(1) default('0')"` // 是否为外链（1是 0否）
	IsCache        string `xorm:"varchar(1) default('0')"` // 是否缓存（1缓存 0不缓存）
	MenuType       string `xorm:"varchar(1) default('0')"` // 菜单类型（M目录 C菜单 F按钮）
	Visible        string `xorm:"varchar(1) default('1')"` // 菜单状态（1显示 0隐藏）
	Status         string `xorm:"varchar(1) default('1')"` // 菜单状态（1正常 0停用）
	Perms          string `xorm:"varchar(100)"`            // 权限标识
	Icon           string `xorm:"varchar(100)"`            // 菜单图标
	dom.BaseStruct `xorm:"extends"`
}

// SysMenuVo 映射
type SysMenuVo struct {
	MenuId    int64  `json:"menuId,omitempty" xorm:"pk"`
	MenuName  string `json:"menuName,omitempty"`
	ParentId  int64  `json:"parentId,omitempty"`
	OrderNum  int    `json:"orderNum,omitempty"`
	Path      string `json:"path,omitempty"`
	Component string `json:"component,omitempty"`
	Query     string `json:"query,omitempty"`
	IsFrame   string `json:"isFrame,omitempty"`
	IsCache   string `json:"isCache,omitempty"`
	MenuType  string `json:"menuType,omitempty"`
	Visible   string `json:"visible,omitempty"`
	Status    string `json:"status,omitempty"`
	Perms     string `json:"perms,omitempty"`
	Icon      string `json:"icon,omitempty"`
}

// SysMenuPageVo 页面
type SysMenuPageVo struct {
	SysMenuVo    `xorm:"extends"`
	dom.BaseJson `xorm:"extends"`
	Children     []*SysMenuPageVo `json:"children,omitempty" xorm:"-"`
}

// SysMenuDto 传输
type SysMenuDto struct {
	IsMenu bool
	SysMenuPageVo
	dom.PageVo
}

func (m *SysMenuDto) Validator() error {
	if m.PageNum < 1 {
		m.PageNum = 1
	}
	if m.PageSize < 1 {
		m.PageSize = 10
	}
	return nil
}

// RouterVo 前端路由结构
type RouterVo struct {
	Name       string     `json:"name,omitempty"`       // 路由名字
	Path       string     `json:"path,omitempty"`       // 路由地址
	Hidden     bool       `json:"hidden,omitempty"`     // 是否隐藏路由，当设置 true 的时候该路由不会再侧边栏出现
	Redirect   string     `json:"redirect,omitempty"`   // 重定向地址，当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
	Component  string     `json:"component,omitempty"`  // 组件地址
	Query      string     `json:"query,omitempty"`      // 路由参数：如 {"id": 1, "name": "ry"}
	AlwaysShow bool       `json:"alwaysShow,omitempty"` // 当你一个路由下面的 children 声明的路由大于1个时，自动会变成嵌套的模式--如组件页面
	Meta       MetaVo     `json:"meta,omitempty"`       // 其他元素
	Children   []RouterVo `json:"children,omitempty"`   // 子路由
}

// MetaVo 前端面包屑结构
type MetaVo struct {
	Title   string `json:"title,omitempty"`   // 设置该路由在侧边栏和面包屑中展示的名字
	Icon    string `json:"icon,omitempty"`    // 设置该路由的图标，对应路径src/assets/icons/svg
	NoCache bool   `json:"noCache,omitempty"` // 设置为true，则不会被 <keep-alive>缓存
	Link    string `json:"line,omitempty"`    // 内链地址（http(s)://开头）
}

func (m *SysMenuPageVo) BuildMenuTree(menuItems []*SysMenuPageVo) []*SysMenuPageVo {
	menuMap := make(map[int]*SysMenuPageVo)
	var roots []*SysMenuPageVo
	// 将菜单项按照ID存储到map中
	for _, item := range menuItems {
		menuMap[int(item.MenuId)] = item
	}
	// 构建菜单树结构
	for _, item := range menuItems {
		parent := menuMap[int(item.ParentId)]
		if parent != nil {
			parent.Children = append(parent.Children, item)
		} else {
			roots = append(roots, item)
		}
	}
	// 排序
	sortMenuTreeByWeight(&roots)
	return roots
}

// 排序
func sortMenuTreeByWeight(nodes *[]*SysMenuPageVo) {
	sort.Slice(*nodes, func(i, j int) bool {
		return (*nodes)[i].OrderNum < (*nodes)[j].OrderNum
	})
	for i := range *nodes {
		sortMenuTreeByWeight(&(*nodes)[i].Children)
	}
}
